#include "sessiondialog.h"
#include "sessionmanager.h"
#include "common.h"
#include <QDateTime>
#include <QScrollBar>
#include <QTableWidgetItem>
#include <QTableView>
#include <QStandardItemModel>
#include <QHeaderView>
#include <QVBoxLayout>
#include <QLabel>

SessionDialog::SessionDialog(SessionManager *sessionManager, const ProtocolSession &session,
                           const QList<PacketInfo> &allPackets, QWidget *parent)
    : QDialog(parent)
    , m_sessionManager(sessionManager)
    , m_session(session)
    , m_allPackets(allPackets)
    , m_packetModel(nullptr)
{
    // 从所有数据包中筛选出与会话相关的数据包
    m_sessionPackets = getSessionPackets();
    
    // 初始化UI
    initUI();
    populatePacketTable();
    displaySessionDetails();
    
    // 设置窗口标题
    setWindowTitle(QString("会话详情 - %1").arg(session.typeString));
    
    // 设置窗口大小
    resize(900, 700);
}

SessionDialog::~SessionDialog()
{
    delete m_packetModel;
}

void SessionDialog::initUI()
{
    // 创建主布局
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    
    // 创建标签页控件
    m_tabWidget = new QTabWidget(this);
    
    // 创建数据包表格标签页
    QWidget *packetTab = new QWidget();
    QVBoxLayout *packetLayout = new QVBoxLayout(packetTab);
    
    // 创建数据包表格
    m_packetTable = new QTableView();
    m_packetModel = new QStandardItemModel(this);
    
    // 设置表头
    QStringList headers;
    headers << "序号" << "时间" << "源MAC" << "目标MAC" << "源IP" << "目标IP" << "协议" << "长度";
    m_packetModel->setHorizontalHeaderLabels(headers);
    
    // 设置表格属性
    m_packetTable->setModel(m_packetModel);
    m_packetTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    m_packetTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_packetTable->setSortingEnabled(true);
    
    // 自动调整列宽
    for (int i = 0; i < headers.size(); i++) {
        m_packetTable->horizontalHeader()->setSectionResizeMode(i, QHeaderView::Interactive);
    }
    
    // 连接点击信号
    connect(m_packetTable, &QTableView::clicked, this, &SessionDialog::onPacketTableClicked);
    
    // 将表格添加到布局
    packetLayout->addWidget(m_packetTable);
    
    // 创建数据包详情文本框
    m_packetDetailText = new QTextEdit();
    m_packetDetailText->setReadOnly(true);
    packetLayout->addWidget(new QLabel("数据包详情:"));
    packetLayout->addWidget(m_packetDetailText);
    
    // 添加数据包标签页
    m_tabWidget->addTab(packetTab, "数据包列表");
    
    // 创建会话详情标签页
    QWidget *sessionTab = new QWidget();
    QVBoxLayout *sessionLayout = new QVBoxLayout(sessionTab);
    
    // 创建会话详情文本框
    m_sessionDetailText = new QTextEdit();
    m_sessionDetailText->setReadOnly(true);
    sessionLayout->addWidget(m_sessionDetailText);
    
    // 添加会话详情标签页
    m_tabWidget->addTab(sessionTab, "会话详情");
    
    // 将标签页添加到主布局
    mainLayout->addWidget(m_tabWidget);
}

void SessionDialog::populatePacketTable()
{
    // 清空表格
    m_packetModel->clear();
    QStringList headers;
    headers << "序号" << "时间" << "源MAC" << "目标MAC" << "源IP" << "目标IP" << "协议" << "长度";
    m_packetModel->setHorizontalHeaderLabels(headers);
    
    // 填充表格
    for (const auto &packet : m_sessionPackets) {
        QList<QStandardItem *> rowItems;
        rowItems.append(new QStandardItem(QString::number(packet.index)));
        rowItems.append(new QStandardItem(packet.timestamp));
        rowItems.append(new QStandardItem(packet.sourceMac));
        rowItems.append(new QStandardItem(packet.destMac));
        rowItems.append(new QStandardItem(packet.sourceIp));
        rowItems.append(new QStandardItem(packet.destIp));
        rowItems.append(new QStandardItem(packet.protocol));
        rowItems.append(new QStandardItem(QString::number(packet.length)));
        
        // 存储数据包索引作为数据
        rowItems[0]->setData(packet.index, Qt::UserRole);
        
        m_packetModel->appendRow(rowItems);
    }
    
    // 如果有数据包，默认选中第一个
    if (m_packetModel->rowCount() > 0) {
        m_packetTable->selectRow(0);
        onPacketTableClicked(m_packetModel->index(0, 0));
    }
}

void SessionDialog::displaySessionDetails()
{
    QString details;
    
    // 基本信息
    details += "=== 会话基本信息 ===\n";
    details += QString("协议类型: %1\n").arg(m_session.typeString);
    
    // 获取状态字符串
    QString stateStr;
    switch (m_session.state) {
    case SessionState::ACTIVE:
        stateStr = "活跃";
        break;
    case SessionState::COMPLETED:
        stateStr = "已完成";
        break;
    case SessionState::ERROR:
        stateStr = "错误";
        break;
    case SessionState::TIMED_OUT:
        stateStr = "超时";
        break;
    }
    
    details += QString("状态: %1\n").arg(stateStr);
    details += QString("开始时间: %1\n").arg(m_session.startTime.toString("yyyy-MM-dd hh:mm:ss.zzz"));
    
    if (m_session.endTime.isValid()) {
        details += QString("结束时间: %1\n").arg(m_session.endTime.toString("yyyy-MM-dd hh:mm:ss.zzz"));
    }
    
    // 计算持续时间
    qint64 durationMs = m_session.getDurationMs();
    QString durationStr;
    if (durationMs < 1000) {
        durationStr = QString("%1 ms").arg(durationMs);
    } else {
        durationStr = QString("%1 s").arg(durationMs / 1000.0, 0, 'f', 1);
    }
    
    details += QString("持续时间: %1\n").arg(durationStr);
    details += QString("客户端: %1:%2\n").arg(m_session.clientAddress).arg(m_session.clientPort);
    details += QString("服务器: %1:%2\n").arg(m_session.serverAddress).arg(m_session.serverPort);
    details += QString("数据包数: %1\n").arg(m_session.packetIndices.size());
    details += QString("总字节数: %1\n").arg(m_session.totalBytes);
    details += QString("请求次数: %1\n").arg(m_session.requestCount);
    details += QString("响应次数: %1\n\n").arg(m_session.responseCount);
    
    // 会话摘要
    if (!m_session.summary.isEmpty()) {
        details += "=== 会话摘要 ===\n";
        details += m_session.summary;
        details += "\n\n";
    }
    
    // 协议特定信息
    if (!m_session.additionalInfo.isEmpty()) {
        details += "=== 协议详情 ===\n";
        
        // 按类型和序号排序显示请求和响应
        QMap<QString, QString> sortedInfo;
        
        // 先添加请求
        for (int i = 1; i <= m_session.requestCount; i++) {
            QString key = QString("Request%1").arg(i);
            if (m_session.additionalInfo.contains(key)) {
                sortedInfo[key] = m_session.additionalInfo[key];
            }
        }
        
        // 再添加响应
        for (int i = 1; i <= m_session.responseCount; i++) {
            QString key = QString("Response%1").arg(i);
            if (m_session.additionalInfo.contains(key)) {
                sortedInfo[key] = m_session.additionalInfo[key];
            }
        }
        
        // 添加命令（FTP等协议）
        for (int i = 1; i <= 100; i++) { // 限制最大命令数
            QString key = QString("Command%1").arg(i);
            if (!m_session.additionalInfo.contains(key)) {
                break;
            }
            sortedInfo[key] = m_session.additionalInfo[key];
        }
        
        // 显示排序后的信息
        for (auto it = sortedInfo.constBegin(); it != sortedInfo.constEnd(); ++it) {
            details += QString("%1: %2\n").arg(it.key()).arg(it.value());
        }
    }
    
    // 显示在会话详情文本框中
    m_sessionDetailText->setPlainText(details);
}

void SessionDialog::onPacketTableClicked(const QModelIndex &index)
{
    if (!index.isValid()) {
        return;
    }
    
    int row = index.row();
    
    // 获取数据包索引
    QModelIndex idIndex = m_packetModel->index(row, 0);
    int packetIndex = idIndex.data(Qt::UserRole).toInt();
    
    // 查找对应的数据包
    for (const auto &packet : m_sessionPackets) {
        if (packet.index == packetIndex) {
            displayPacketDetails(packet);
            break;
        }
    }
}

void SessionDialog::displayPacketDetails(const PacketInfo &packet)
{
    QString details;
    
    // 基本信息
    details += "=== 基本信息 ===\n";
    details += QString("序号: %1\n").arg(packet.index);
    details += QString("时间戳: %1\n").arg(packet.timestamp);
    details += QString("长度: %1 字节\n\n").arg(packet.length);
    
    // 以太网信息
    details += "=== 数据链路层 (以太网) ===\n";
    details += packet.linkLayerDetail;
    details += "\n";
    
    // IP信息
    details += "=== 网络层 (IP) ===\n";
    details += packet.networkLayerDetail;
    details += "\n";
    
    // TCP/UDP信息
    details += "=== 传输层 ===\n";
    details += packet.transportLayerDetail;
    details += "\n";
    
    // 应用层信息
    details += "=== 应用层 ===\n";
    details += packet.applicationLayerDetail;
    
    m_packetDetailText->setPlainText(details);
}

QList<PacketInfo> SessionDialog::getSessionPackets()
{
    QList<PacketInfo> sessionPackets;
    
    // 从所有数据包中筛选出与会话相关的数据包
    for (int packetIndex : m_session.packetIndices) {
        for (const auto &packet : m_allPackets) {
            if (packet.index == packetIndex) {
                sessionPackets.append(packet);
                break;
            }
        }
    }
    
    return sessionPackets;
}